package com.hisense.hiioc.formtable.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.hisense.hiioc.formtable.domain.User;
import com.hisense.hiioc.formtable.mapper.UserMapper;
import com.hisense.hiioc.formtable.util.JsonResult;
import com.hisense.hiioc.formtable.util.MD5;
import com.hisense.hiioc.formtable.util.VerifyCodeUtils;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.OutputStream;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
public class HtmlController {

    @Autowired
    private UserMapper userMapper;

    @RequestMapping("/")
    public String main(Model model) {
        return "customize_form";
    }

    @RequestMapping("/index")
    public String index(Model model) {
        return "customize_form";
    }

    @RequestMapping("/customize_form")
    public String customizeForm(Model model) {
        return "customize_form";
    }

    @RequestMapping("/customize_field")
    public String customizeField(Model model) {
        return "customize_field";
    }

    @RequestMapping("/fill_form")
    public String fillForm(Model model) {
        return "fill_form";
    }

    @RequestMapping("/login")
    public String login(Model model) {
        return "login";
    }

    @RequestMapping("/404")
    public String error404(Model model) {
        return "404";
    }

    @ApiOperation(value = "登录接口", notes = "login页面的登录专用接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "用户名", required = true, dataType = "String" ,paramType = "query"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "String" ,paramType = "query"),
            @ApiImplicitParam(name = "verifyCode", value = "验证码", required = true, dataType = "String" ,paramType = "query"),
            @ApiImplicitParam(name = "timeStamp", value = "时间戳", required = true, dataType = "String" ,paramType = "query"),
            @ApiImplicitParam(name = "token", value = "token值，前四个参数顺序拼接后md5的值", required = true, dataType = "String" ,paramType = "query")
    })
    @PostMapping(value = "/loginVerify")
    @ResponseBody
    public JsonResult loginVerify(@RequestParam("username") String username,
                                  @RequestParam("password") String password,
                                  @RequestParam("verifyCode") String verifyCode,
                                  @RequestParam("timeStamp") String timeStamp,
                                  @RequestParam("token") String token,
                                  HttpSession session,
                                  HttpServletRequest request) throws Exception {

        JsonResult jsonResult = new JsonResult();

        //拼接验证token的字符串
        String pre_encrypt_str = username + password + verifyCode + timeStamp + "";
        MD5 md5 = new MD5();
        //获取验证的token值，和前端传过来的token比较
        String ver_token = md5.encrypt(pre_encrypt_str);
        if (!ver_token.equals(token)) {
            //token验证不通过
            jsonResult.errorMsg("哎呦，出错了哦！");
        } else {
            //token验证通过
//            String ip = Func.getRemoteAddress(request);
            System.out.println(username+"--"+password+"--"+verifyCode + "--" + timeStamp + "--"+token + "--");
//            System.out.println("ver_token = " + ver_token);
            String verCode = session.getAttribute("verCode") + "";
            try {
                LocalDateTime codeTime = (LocalDateTime) session.getAttribute("codeTime");
                if (codeTime == null ) {
                    codeTime = LocalDateTime.of(1970,01, 01,01,01);
                }
                //先判断验证码是否超时，验证时长为30s
                Duration duration = Duration.between(codeTime,LocalDateTime.now());
                long timeMinus = duration.toMillis()/1000;
                if (timeMinus > 30L) {
                    jsonResult.errorMsg(-1, "验证码超时，请刷新验证码！");
                } else {
                    verifyCode = verifyCode.toLowerCase();
                    if (verCode.equals(verifyCode)) {
                        //通过超时验证后，开始验证用户名和密码
                        Map<String, Object> map = new HashMap<>();
                        map.put("username", username);
                        map.put("password", password);
                        List<User> list = userMapper.checkUsernameAndPassword(map);
                        if (list.size() > 0) {
                            ObjectMapper mapper = new ObjectMapper();
                            String user_json = mapper.writeValueAsString(list.get(0));
                            session.setAttribute("username",username);
                            session.setAttribute("user",user_json);
                            jsonResult.ok();
                        } else {
                            jsonResult.errorMsg("用户名或密码错误！");
                        }
                    } else {
                        jsonResult.errorMsg(-2,"验证码输入错误！");
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return jsonResult;
    }

    /**
     * 外部调用接口
     * http://localhost:8080/loginLinkVerify?username=admin&verifyCode=123456&timeStamp=1563447128629&token=d48a6c82a9d0a092058bdeb2c1ae1b49
     * @param username
     * @param verifyCode
     * @param timeStamp
     * @param token
     * @param session
     * @param model
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "外部链接调用接口",notes = "把username+verifyCode+timeStamp参数拼接后，md5作为token值")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "用户名", required = true, dataType = "String" ,paramType = "query"),
            @ApiImplicitParam(name = "verifyCode", value = "验证码", required = true, dataType = "String" ,paramType = "query"),
            @ApiImplicitParam(name = "timeStamp", value = "毫秒数字时间戳，通过new Date().getTime()获取，10分钟后超时", required = true, dataType = "Long" ,paramType = "query"),
            @ApiImplicitParam(name = "token", value = "token，前三个参数拼接后的md5值", required = true, dataType = "String" ,paramType = "query")
    })
    @GetMapping(value = "/loginLinkVerify")
    public String loginLinkVerify(@RequestParam("username") String username,
                                  @RequestParam("verifyCode") String verifyCode,
                                  @RequestParam("timeStamp") Long timeStamp,
                                  @RequestParam("token") String token,
                                  HttpSession session,
                                  Model model)  {
//        System.out.println(username+"--"+"--"+verifyCode + "--" + timeStamp + "--"+token + "--");
        String jsonResult = "error";
//        long verifyTime = Long.parseLong(timeStamp); //参数中时间戳
        long chaSecond = (System.currentTimeMillis() - timeStamp)/1000;
        if (chaSecond < 600) {
            //拼接验证token的字符串
            String pre_encrypt_str = username + verifyCode + timeStamp + "";
            MD5 md5 = new MD5();
            //获取验证的token值，和前端传过来的token比较
            String ver_token = md5.encrypt(pre_encrypt_str);
            if (!ver_token.equals(token)) {
                //token验证不通过
                jsonResult = "error";
            } else {
                //token验证通过
                session.setAttribute("username",username);
                jsonResult =  "customize_form";
            }
        }
        return jsonResult;
    }

    @ApiOperation("登录页验证码生成接口")
    @GetMapping(value = "/getVerfyImage")
    private void getVerfyImage(HttpServletRequest request, HttpServletResponse response) throws IOException {

        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("image/jpeg");
        // 生成随机字串
        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);
        // 存入会话session
        HttpSession session = request.getSession(true);
        // 删除以前的
        session.removeAttribute("verCode");
        session.removeAttribute("codeTime");
        String code = verifyCode.toLowerCase();
//        System.out.println(code);
        session.setAttribute("verCode", code);
        session.setAttribute("codeTime", LocalDateTime.now());
        // 生成图片
        int w = 100, h = 30;
        OutputStream out = response.getOutputStream();
        VerifyCodeUtils.outputImage(w, h, out, verifyCode);
    }

    @GetMapping("/logout")
    public String logout(HttpSession session) {
        // 移除session
        session.removeAttribute("username");
        return "redirect:/login";
    }
}
